import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
import { initWebSocket } from './websocket.js';
import { getLocalIP } from './localip.js';
import { HTTP_PORT, WS_PORT } from './common.js';
import fs from 'fs';
import multer from 'multer';
import BaiduOCR from './ocr.js';
import dotenv from 'dotenv';

// 加载环境变量
dotenv.config();

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const app = express();
app.use(express.json({ limit: '100mb' }));

// CORS 设置，允许来自 Vite 开发端口的跨域请求
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  if (req.method === 'OPTIONS') {
    return res.sendStatus(204);
  }
  next();
});

// 初始化OCR服务
const ocr = new BaiduOCR();

// 配置multer用于文件上传
const upload = multer({ 
  storage: multer.memoryStorage(),
  limits: {
    fileSize: 10 * 1024 * 1024, // 限制10MB
    files: 1
  },
  fileFilter: (req, file, cb) => {
    // 只允许图片文件
    if (file.mimetype.startsWith('image/')) {
      cb(null, true);
    } else {
      cb(new Error('只支持图片文件'), false);
    }
  }
});

const initServer = () => {
  return new Promise((resolve, reject) => {
    // 设置静态文件服务 - 指向 react-chat/public 目录
    const publicDir = path.join(__dirname, '..', 'public');
    app.use('/public', express.static(publicDir));

    // 设置静态文件服务 - 指向 react-chat/dist 目录（Vite 构建输出）
    const distDir = path.join(__dirname, '..', 'dist');
    app.use(express.static(distDir));

    // ========== HTTP 文件上传接口 ==========
    // 秒传检查
    app.post('/upload/check', (req, res) => {
      try {
        const { fileHash } = req.body || {};
        if (!fileHash) return res.status(400).json({ error: 'fileHash required' });
        const idxPath = path.join(__dirname, '..', 'public', 'fileIndex.json');
        if (fs.existsSync(idxPath)) {
          const json = JSON.parse(fs.readFileSync(idxPath, 'utf-8'));
          const record = json[fileHash];
          if (record && record.fileLink) {
            return res.json({ exists: true, filePath: record.fileLink });
          }
        }
        return res.json({ exists: false });
      } catch (e) {
        console.error('upload/check error:', e);
        return res.status(500).json({ error: 'internal error' });
      }
    });

    // 上传分片（JSON base64）
    app.post('/upload/chunk', (req, res) => {
      try {
        const { fileHash, chunkIndex, totalChunks, data, fileName } = req.body || {};
        if (
          typeof fileHash !== 'string' ||
          typeof chunkIndex !== 'number' ||
          typeof totalChunks !== 'number' ||
          typeof data !== 'string'
        ) {
          return res.status(400).json({ error: 'invalid payload' });
        }

        const tempDir = path.join(__dirname, '..', 'temp', String(fileHash));
        if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir, { recursive: true });
        const chunkPath = path.join(tempDir, `chunk_${chunkIndex}`);
        const buf = Buffer.from(data, 'base64');
        fs.writeFileSync(chunkPath, buf);
        return res.json({ ok: true });
      } catch (e) {
        console.error('upload/chunk error:', e);
        return res.status(500).json({ error: 'internal error' });
      }
    });

    // 合并分片
    app.post('/upload/complete', async (req, res) => {
      try {
        const { fileHash, fileName, totalChunks, fileSize } = req.body || {};
        if (
          typeof fileHash !== 'string' ||
          typeof fileName !== 'string' ||
          typeof totalChunks !== 'number'
        ) {
          return res.status(400).json({ error: 'invalid payload' });
        }

        const chunkTempDir = path.join(__dirname, '..', 'temp', String(fileHash));
        const publicDir = path.join(__dirname, '..', 'public');
        const uploadTempDir = path.join(publicDir, 'temp');
        if (!fs.existsSync(uploadTempDir)) fs.mkdirSync(uploadTempDir, { recursive: true });

        const lastDotIndex = fileName.lastIndexOf('.');
        const extension = lastDotIndex > 0 ? fileName.substring(lastDotIndex) : '';
        const outName = `${Date.now()}_${Math.random().toString(16).slice(2)}${extension}`;
        const outPath = path.join(uploadTempDir, outName);

        const ws = fs.createWriteStream(outPath);
        for (let i = 0; i < totalChunks; i++) {
          const cPath = path.join(chunkTempDir, `chunk_${i}`);
          if (!fs.existsSync(cPath)) {
            ws.close();
            return res.status(400).json({ error: `missing chunk ${i}` });
          }
          const buf = fs.readFileSync(cPath);
          ws.write(buf);
          fs.unlinkSync(cPath);
        }
        ws.end();
        await new Promise((resolve, reject) => {
          ws.on('finish', resolve);
          ws.on('error', reject);
        });

        if (fs.existsSync(chunkTempDir)) {
          try { fs.rmdirSync(chunkTempDir, { recursive: true }); } catch {}
        }

        const fileLink = `/public/temp/${outName}`;
        // 更新文件索引
        const idxPath = path.join(__dirname, '..', 'public', 'fileIndex.json');
        let idx = {};
        if (fs.existsSync(idxPath)) {
          try { idx = JSON.parse(fs.readFileSync(idxPath, 'utf-8')); } catch {}
        }
        idx[String(fileHash)] = {
          fileLink,
          fileName,
          fileSize: typeof fileSize === 'number' ? fileSize : undefined
        };
        fs.writeFileSync(idxPath, JSON.stringify(idx, null, 2));

        // 返回完整的文件URL，包含服务器地址
        const fullFilePath = `http://${req.get('host')}${fileLink}`;
        return res.json({ ok: true, filePath: fullFilePath });
      } catch (e) {
        console.error('upload/complete error:', e);
        return res.status(500).json({ error: 'internal error' });
      }
    });

    // ========== OCR 文字识别接口 ==========
    // 单张图片OCR识别
    app.post('/api/ocr/recognize', upload.single('image'), async (req, res) => {
      try {
        if (!req.file) {
          return res.status(400).json({ 
            success: false, 
            error: '请上传图片文件' 
          });
        }

        console.log(`收到OCR请求: ${req.file.originalname}, 大小: ${req.file.size} bytes`);

        // 检查文件大小
        if (req.file.size > 10 * 1024 * 1024) {
          return res.status(400).json({
            success: false,
            error: '图片文件过大，请上传10MB以下的图片'
          });
        }

        // 执行OCR识别
        const result = await ocr.recognizeText(req.file.buffer, {
          language_type: 'CHN_ENG', // 中英文混合
          detect_direction: true,    // 检测方向
          detect_language: true      // 检测语言
        });
        
        res.json({
          success: true,
          data: result,
          message: '识别成功'
        });
      } catch (error) {
        console.error('OCR识别失败:', error);
        
        // 根据错误类型返回不同的状态码
        let statusCode = 500;
        let errorMessage = '识别失败，请稍后重试';
        
        if (error.message.includes('访问令牌')) {
          statusCode = 401;
          errorMessage = 'OCR服务配置错误，请联系管理员';
        } else if (error.message.includes('超时')) {
          statusCode = 408;
          errorMessage = '识别超时，请稍后重试';
        } else if (error.message.includes('百度OCR错误')) {
          statusCode = 400;
          errorMessage = `识别失败: ${error.message}`;
        }
        
        res.status(statusCode).json({
          success: false,
          error: errorMessage,
          details: process.env.NODE_ENV === 'development' ? error.message : undefined
        });
      }
    });

    // 批量OCR识别接口
    app.post('/api/ocr/recognize-batch', upload.array('images', 5), async (req, res) => {
      try {
        if (!req.files || req.files.length === 0) {
          return res.status(400).json({
            success: false,
            error: '请上传图片文件'
          });
        }

        if (req.files.length > 5) {
          return res.status(400).json({
            success: false,
            error: '最多支持5张图片同时识别'
          });
        }

        console.log(`收到批量OCR请求: ${req.files.length} 张图片`);

        // 检查文件大小
        for (const file of req.files) {
          if (file.size > 10 * 1024 * 1024) {
            return res.status(400).json({
              success: false,
              error: `图片 ${file.originalname} 过大，请上传10MB以下的图片`
            });
          }
        }

        // 执行批量识别
        const imageBuffers = req.files.map(file => file.buffer);
        const result = await ocr.recognizeMultipleImages(imageBuffers, {
          language_type: 'CHN_ENG',
          detect_direction: true,
          detect_language: true
        });

        res.json({
          success: true,
          data: result,
          message: `批量识别完成，成功 ${result.successCount} 张，失败 ${result.errorCount} 张`
        });
      } catch (error) {
        console.error('批量OCR识别失败:', error);
        res.status(500).json({
          success: false,
          error: '批量识别失败，请稍后重试'
        });
      }
    });

    // 健康检查接口
    app.get('/api/health', (req, res) => {
      res.json({
        success: true,
        message: 'OCR服务运行正常',
        timestamp: new Date().toISOString(),
        version: '1.0.0'
      });
    });

    // 所有其他路由都返回 index.html（SPA 路由支持）
    app.get('*', (req, res) => {
      res.sendFile(path.join(distDir, 'index.html'));
    });

    // 启动 HTTP 服务器
    app.listen(HTTP_PORT, '0.0.0.0', () => {
      console.log('✅ HTTP服务器启动成功');
      console.log(`HTTP服务器监听: http://127.0.0.1:${HTTP_PORT}`);
      console.log(`HTTP服务器监听: http://${getLocalIP()}:${HTTP_PORT}`);
      
      // 启动 WebSocket 服务器
      initWebSocket(HTTP_PORT, WS_PORT);
      
      resolve({
        webPort: HTTP_PORT,
        wsPort: WS_PORT,
        serviceUrl: `http://${getLocalIP()}:${HTTP_PORT}`,
        serviceWsUrl: `ws://${getLocalIP()}:${WS_PORT}`
      });
    });
  });
};

// 启动服务器
if (import.meta.url === `file://${process.argv[1]}`) {
  initServer().catch(console.error);
}

export { initServer };